﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text.RegularExpressions;
using Medianamik.Core;

namespace Medianamik.UI.Mediasend.Logic
{
    /// <summary>
    /// Classe permettant de remplacer les éléments "class=" par des éléments
    /// "style=" dans le code HTML
    /// </summary>
    public class StyleParser
    {
        List<StyleDef> _styles;
        string _message;
        string _cssStyle; 

        public StyleParser() : this ("")
        { }

        public StyleParser(string cssStyle)
        {
            _cssStyle = cssStyle;
        }

        /// <summary>
        /// Fonction principale de "parsing" do document
        /// </summary>
        /// <param name="InMessage"></param>
        /// <returns></returns>
        public string Parse(string InMessage)
        {
            try
            {
                _styles = new List<StyleDef>();
                _message = InMessage;

                //Lister tous les styles définis dans la balise "<style>"
                searchForStyles();

                //Remplacer tous les éléments "class=" par "style="
                replaceStyles();

                //Remplacer les styles a.<nomClasse>.LINK:....{}
                replaceLinks();
            }
            catch (Exception)
            {
                _message = InMessage;
            }

            return _message;
        }

        /// <summary>
        /// Place tous les styles définis comme .<nom du style>{ }
        /// dans une collection
        /// </summary>
        private void searchForStyles()
        { 
            string parsedContent;

            //Trouver les styles .<nom du style> { }
            //L'option "Singleline" est pour ommetre les \n
            var reg = new Regex(@"\.([a-zA-Z0-9]*?)\s*?{(.*?)}", RegexOptions.Singleline);

            //Si le cssStyle n'a pas été spécifié, on regarde à même le contenu HTML
            if (!_cssStyle.IsNullOrEmpty())
                parsedContent = _cssStyle;
            else
                parsedContent = _message;

            foreach (Match regMatch in reg.Matches(parsedContent))
            {
                //Placer le style trouvé dans la collection
                _styles.Add(new StyleDef(regMatch.Groups[1].Value.Replace(" ", "").Replace("\r\n", ""), regMatch.Groups[2].Value.Replace("\r\n", "").Replace("\t", "")));
            }
        }

        /// <summary>
        /// Remplacer tous les éléments "class=" par "style="   
        /// </summary>
        private void replaceStyles()
        {
            Regex reg;

            //Passer en revue tous les styles détectés dans la collection
            foreach (var currentStyle in _styles)
            { 
                //Trouver les tags "class" correspondants à la classe courante
                reg = new Regex("class=\"" + currentStyle.className + "\"");
                //Remplacer les tags class="<nom de la classe>" par un attribut style="<style inline>"
                _message = reg.Replace(_message, "style=\"" + currentStyle.classDefinition + "\"");

                reg = new Regex("class=" + currentStyle.className + "");
                //Remplacer les tags class="<nom de la classe>" par un attribut style="<style inline>"
                _message = reg.Replace(_message, "style=\"" + currentStyle.classDefinition + "\"");
            }
        }

        /// <summary>
        /// Remplacer les définitions a.<classe>.LINK par <a style="..."
        /// </summary>
        private void replaceLinks()
        {
            Regex reg = new Regex(@"a\.([a-zA-Z]*?):link.*?{(.*?)}", RegexOptions.Singleline);

            foreach (Match regMatch in reg.Matches(_message))
            {
                string aStyle = regMatch.Groups[1].Value;
                string aStyleValue = regMatch.Groups[2].Value.Replace("\r\n", "").Replace("\t", "");

                reg = new Regex("class=\"" + aStyle + "\"");
                _message = reg.Replace(_message, "style=\"" + aStyleValue + "\"");

                reg = new Regex("class=" + aStyle);
                _message = reg.Replace(_message, "style=\"" + aStyleValue + "\"");
            }
        }


        /// <summary>
        /// Classe utilitaire pour stocker les 2 valeurs d'un style
        /// <nom du style> et <définition du style>
        /// </summary>
        public class StyleDef
        {
            public string className;
            public string classDefinition;

            public StyleDef(string _className, string _classDefinition)
            {
                className = _className;
                classDefinition = _classDefinition;
            }
        }
    }
}